<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow-IPC: Safety and Permissions</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow-IPC<span id="projectnumber">&#160;1.0.2</span>
   </div>
   <div id="projectbrief">Flow-IPC project: Public API.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

</div><!-- top -->
<div><div class="header">
  <div class="headertitle"><div class="title">Safety and Permissions </div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><center><b>MANUAL NAVIGATION:</b> <a class="el" href="session_app_org.html">Preceding Page</a> - <a class="el" href="universes.html">Next Page</a> - <a href="./pages.html"><b>Table of Contents</b></a> - <a class="el" href="namespaceipc.html"><b>Reference</b></a></center><hr  />
<p >This page is about the mechanics of resource ownership and permissions as (optionally) enforced by <a class="el" href="namespaceipc_1_1session.html" title="Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session conc...">ipc::session</a> and friends; as well as brief recommendations about approaches to this topic in production applications. (Or go back to preceding page: <a class="el" href="session_app_org.html">Sessions: Teardown; Organizing Your Code</a>. <a class="el" href="session_setup.html">Sessions: Setting Up an IPC Context</a>, particularly the parts about the <a class="el" href="structipc_1_1session_1_1App.html" title="A description of an application in this ipc::session inter-process communication universe.">ipc::session::App</a> hierarchy, would also be a natural immediate pre-requisite for the current page.)</p>
<h2>About safety </h2>
<p >You might note that the word we use here is <b>safety</b>, not <em>security</em>. Of course your semantic preferences may differ, but what we mean to convey is this:</p>
<ul>
<li><b>Security</b> is about protection from malicious code, wherever it may live. Flow-IPC deals with IPC, and IPC by definition occurs within one OS instance ("machine"), so the potential malicious code would <em>probably</em> be running within the same machine, possibly even within the same application/process being developed.</li>
<li><b>Safety</b> is about being generally safe with respect to one's data strucutures and code, so that (for example, and for example <em>only</em>):<ul>
<li>If application A wants to talk to application B, it is indeed talking to application B and not application C.<ul>
<li>In particular, if application A talks to B and C, and (say) SHared Memory is used all around, ideally the system should segregate vaddr (virtual address) areas in such a way as to make it impossible or at least unlikely that (due to an un-malicious user-code bug, maybe buffer overflow) data meant for B ends up being read by C. (Customers might see that as <em>security</em>, but in our nomenclature it's about safety, since it's not an attack that caused the potential data breach but the vendor's own bug.)</li>
</ul>
</li>
<li>If application B goes down, gracefully or especially ungracefully, application A should be wary of accessing resources shared (e.g., in SHared Memory &ndash; SHM) with application B, and ideally it would know about the problem as soon as physically possible so as to limit the scope of damage in the meantime.</li>
</ul>
</li>
</ul>
<p >This page is in no way a rigorous overview on how to maintain safety or how Flow-IPC is developed with it in mind. (There may be such a document elsewhere.) We merely wanted to point out that the specific features/APIs we are about to explain are targeting <em>safety</em> as opposed to security. (For example an auth token is used by <a class="el" href="namespaceipc_1_1session.html" title="Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session conc...">ipc::session</a>, but it is not intentionally designed to be cryptographically strong, nor can it be revoked. As another example: Akamai-API internals assume the opposing process is using genuine Flow-IPC internals as well; the sky is the limit for possible damage, if that is not the case.)</p>
<p >The described are a best effort aimed at safety, and as you make decisions about how to apply these APIs to your application(s), do keep in mind the idea is to keep code and data safe(r) from chaos as opposed to protect from malicious/unauthorized code. If the latter is your concern, you must take your own additional measures.</p>
<h2>Specific safety mechanisms </h2>
<p >Again, our goal here is not to provide a rigorous overview of the Flow-IPC safety story, though such documents may exist elsewhere. Here is a short compendium of potential items of interest.</p>
<p ><a class="anchor" id="shm_safety"></a></p><h3>SHM; zero-copy</h3>
<hr  />
<dl class="section user"><dt>Shared memory: background and related topics</dt><dd>Check these out (possibly before, after, or during perusing this section).<ul>
<li><a href="./session_app_org.html#scope"><b>shared-data scope</b></a>;</li>
<li><a class="el" href="chan_struct_advanced.html">SHM-backed structured messages</a>;</li>
<li><a class="el" href="transport_shm.html">direct access to SHM</a>.</li>
</ul>
</dd></dl>
<hr  />
<p >Via <a class="el" href="namespaceipc_1_1session.html" title="Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session conc...">ipc::session</a> two types of shared memory (SHM) providers (<b>SHM-providers</b>) are supported out of the box. To reiterate, if used &ndash; no matter which you choose &ndash; these are typically, at a minimum, automatically used as backing for <a class="el" href="classipc_1_1transport_1_1struc_1_1Channel.html#a860cc99a701576879ebb5a1db58153cc" title="Encapsulation of any out-message payload sent or meant to be sent via send() (et al) by a *this of th...">ipc::transport::struc::Channel::Msg_out</a>, the out-message quasi-container type (and the corresponding <code>Msg_in</code> type). In addition one can place C++ structures, including ones involving arbitrary combinations of STL-compliant containers (and, if desired, allocator-aware pointers), into SHM.</p>
<p >Firstly, one is not required to use SHM backing. Simply use vanilla <a class="el" href="classipc_1_1session_1_1Session__server.html" title="To be instantiated typically once in a given process, an object of this type asynchronously listens f...">ipc::session::Session_server</a> and <a class="el" href="namespaceipc_1_1session.html#a77d8fda00e1e17f595a6a5d4c44375e7" title="A vanilla Client_session with no optional capabilities.">ipc::session::Client_session</a> as your top-level <code>Session_server_t</code> and <code>Client_session_t</code> aliases (see <a class="el" href="session_setup.html">Sessions: Setting Up an IPC Context</a> snippets), instead of <code><a class="el" href="namespaceipc_1_1session_1_1shm.html" title="ipc::session sub-namespace that groups together facilities for SHM-backed sessions,...">ipc::session::shm</a>::...</code>. This will decrease performance (due to adding a copy on each side) for larger messages and put size limits on the resulting per-message serializations, plus certain algorithms relying on in-place modification become impossible without adding retransmission. However it may be a reasonable trade-off depending. In terms of safety the resulting RAM decoupling (i.e., avoiding shared-access memory) may be worth it in some cases.</p>
<p >Secondly, if one does decide to use SHM backing (which we do encourage, all else being equal), a key safety-related decision is about which of the 2 available SHM-providers to use:</p><ul>
<li><b>SHM-classic</b> (<a class="el" href="namespaceipc_1_1session_1_1shm_1_1classic.html" title="Support for SHM-backed ipc::session sessions and session-servers with the SHM-classic (ipc::shm::clas...">ipc::session::shm::classic</a>); or</li>
<li><b>arena-lending SHM-jemalloc</b> (<a class="el" href="namespaceipc_1_1session_1_1shm_1_1arena__lend_1_1jemalloc.html" title="Support for SHM-backed ipc::session sessions and session-servers with the SHM-jemalloc (ipc::shm::are...">ipc::session::shm::arena_lend::jemalloc</a>).</li>
</ul>
<p >Consider a simple-enough scenario in which applications Ap and Bp have an A-B session going, and each creates/transmits messages and/or manual C++ data structures in SHM-arenas accessible via their respective <code>session-&gt;session_shm()</code> accessors. For now suppose process B never writes into data received from A (only reads) &ndash; and vice versa. Now suppose process B crashes terribly &ndash; perhaps due to a buffer-overflow bug that (say) accidentally wrote into the typically-invisible data used by the memory-manager algorithm to track allocation state (free lists? object size? who knows).</p>
<p >With SHM-classic: <code>session-&gt;session_shm()</code>, on either side, are both really referring to the <em>same</em> SHM arena (in fact, same pool as of this writing). Process B never writes (in our stipulation above) to objects/messages received from A, but process B does its own allocations which <em>do</em> write to the same SHM-pool as one where A-written/allocated data do reside. In fact (as we stipulated) the buffer-overflow bug wrote where it wasn't supposed to within <code>session-&gt;session_shm()</code> pool (from B's perspective)... but that's the same pool as A. And when they allocate "their" respective objects, they're allocating from the same memory area, using a shared set of memory-manager control data (allocation state). So, the bottom line is, A &ndash; having detected B's ill health/death &ndash; cannot safely continue operating on <em>its</em> data structures it has allocated or wants to allocate (or deallocate) subsequently. B died, but A-"owned" data are no longer safe.</p>
<p >The same is true of <code>session-&gt;app_shm()</code> (<a href="./session_app_org.html#scope">app-scope</a> data). If B ever allocates messages and/or obejcts in its <code>session-&gt;app_shm()</code> and then goes down ungracefully, A &ndash; to remain safe-ish &ndash; must drop <em>all</em> app-scope data thus affecting potentially all other sessions A has ongoing. In fact, SHM-classic's operation involves B writing to the shared SHM-pool even if it, itself, <em>never</em> allocates out-messages or structures (i.e., is logically entirely read-only). (Internally, when one <code>lend_object()</code>s an object from A to <code>borrow_object()</code>ing B, SHM-classic atomically-increments a hidden ref-count near the object. <a class="el" href="classipc_1_1transport_1_1struc_1_1Channel.html#ae645cb58ad9ea6374970f1f32c5da448" title="In the synchronous/non-blocking manner of Blob_sender::send_blob() or Native_handle_sender::send_nati...">ipc::transport::struc::Channel::send()</a> and <code>*sync_request()</code> internally invoke these lend-borrow operations as well.) So, even if B is logically read-only, an ungraceful death of B still involves <em>some</em> safety risk to A-owned data in SHM.</p>
<p >Now consider SHM-jemalloc. A's <code>session-&gt;session_shm()</code> is a SHM-arena maintained (internally) by A; B's <code>session-&gt;session_shm()</code> is a completely separate arena maintained by B. B went down? Though the user code that uses SHM-jemalloc can remain (almost) completely identical to SHM-classic alternative, once B is down: Data allocated and written by A, in its <code>session-&gt;session_shm()</code>, remain safe to use.</p>
<p >Furthermore, again, consider data allocated and living in <code>session-&gt;app_shm()</code> (app-scope data). With SHM-jemalloc, there <em>is</em> no <code>session-&gt;app_shm()</code> in B, so that's moot (see note just below on this and other such items). However, lend-from-A operations do not involve writing anything by B or in B's arena(s), unlike with SHM-classic. So nothing B can do via SHM can somehow poison <code>session-&gt;app_shm()</code> and thus poison other sessions connected to A, then or subsequently.</p>
<p >Lastly, SHM-jemalloc (as of this writing, though this could be optionally changed in a subsequent version) simply disallows A to write in objects constructed by B and vice versa. (See note just below.) Naturally this reduces what algorithms can be used, albeit only with direct C++-object storing in SHM, not <code>struc::Channel</code> messages &ndash; which as of this writing are always read-only on the receiving side in any case. Receiver can't write to sender-created objects; mutexes cannot be stored in SHM (as locking/unlocking is a write). This is a deficiency or lacking capability from one point of view, yes; but from the point of view of safety it can be seen as an advantage. By limiting algorithms to that certain style, overall safety of the system goes up, as entropy goes down.</p>
<hr  />
<p ><a class="anchor" id="shm_safety_other_considerations"></a></p><dl class="section user"><dt>Other aspects of SHM-classic versus SHM-jemalloc choice</dt><dd>Safety is a major factor w/r/t which to choose, but it is not the <em>only</em> factor. This is outside our scope here, but for convenience we restate: Spoiler alert: SHM-classic is fast/low-risk to set up and tear down (meaning, the logic executed during session/server opening and closing), lightning-fast in lend/borrow operations, easy to debug and understand, allows full symmetric read/write, and provides app-scope arena allocation on both sides (as opposed to only the session-server side). SHM-jemalloc, in contrast, lacks those benefits but packs a <em>huge</em> benefit that arguably more than makes up for them: the use of commercial-grade <em>jemalloc <code>malloc()</code> memory manager</em> for heap management, at allocation (<code>Arena::construct&lt;T&gt;(...)</code>) and deallocation time. (SHM-classic uses a <a href="https://www.boost.org/doc/libs/1_82_0/doc/html/interprocess/memory_algorithms.html">built-in algorithm</a> by the Boost guys, or whatever replacement one can cook up to replace it. Out of the box this lacks jemalloc perf-boosting goodies like mature fragmentation avoidance algorithms and thread caching: things we take for granted in conventional stack-and-heap-based memory use. It may be absolutely fine for many applications, but it is no commerical-grade <code>malloc()</code>er.)</dd></dl>
<hr  />
<dl class="section user"><dt>Message queues (MQs) in SHM</dt><dd><a class="el" href="namespaceipc_1_1transport.html" title="Flow-IPC module providing transmission of structured messages and/or low-level blobs (and more) betwe...">ipc::transport</a> provides the <em>MQ (message queue)</em> low-level transport mechanism, parameterized on <a class="el" href="classipc_1_1transport_1_1Persistent__mq__handle.html" title="A documentation-only concept defining the behavior of an object representing a light-weight handle to...">ipc::transport::Persistent_mq_handle</a> concept for which 2 impls are available out of the box. One of them is <a class="el" href="classipc_1_1transport_1_1Bipc__mq__handle.html" title="Implements the Persistent_mq_handle concept by thinly wrapping bipc::message_queue,...">ipc::transport::Bipc_mq_handle</a> (in <a class="el" href="namespaceipc_1_1session.html" title="Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session conc...">ipc::session</a> enabled using the MQ-type <code>MqType::BIPC</code> in session-type template knob). This is based on the boost.ipc <a href="https://www.boost.org/doc/libs/1_82_0/doc/html/interprocess/synchronization_mechanisms.html#interprocess.synchronization_mechanisms.message_queue"><code>message_queue</code> API</a>. That API's impl, in turn, uses a SHM pool per MQ (in our case a channel, if configured to use MQs, uses 2 MQs, 1 for traffic in each direction). (Formally speaking the documentation does not even mention it, but perusing its straightforward source code makes it clear.) We mention this for completeness; whether you consider this a significant part of your SHM-safety story is your call. Do note this is 100% orthogonal to SHM-classic and/or SHM-jemalloc use in the same application. (That said, algorithmically, boost.ipc essentially maintains a SHM-classic arena per MQ.)</dd></dl>
<hr  />
<dl class="section user"><dt>Mandatory cross-process garbage collection</dt><dd>When speaking of safety, it should be noted that standard use of either SHM-provider, especially via <a class="el" href="namespaceipc_1_1session.html" title="Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session conc...">ipc::session</a>, and any likely SHM-provider(s) to be added over time, garbage-collection of constructed-in-SHM objects is essentially mandatory. <code>Arena::construct&lt;T&gt;(...)</code> always returns <code>shared_ptr&lt;T&gt;</code>, and &ndash; quite importantly &ndash; regardless of SHM-provider, <code>borrow_object()</code> on the receiving side also returns <code>shared_ptr&lt;T&gt;</code>. Critically, the object is destroyed when, and only when, <em>all</em> cross-process <code>shared_ptr</code> groups for a given object in SHM have reached ref-count=zero. Hence, assuming normative use of <code>shared_ptr</code> (not doing <code>delete p.get()</code>, etc.), leaks and double-free should not exist.</dd></dl>
<dl class="section user"><dt></dt><dd><a class="el" href="classipc_1_1shm_1_1stl_1_1Stateless__allocator.html" title="Stateless allocator usable with STL-compliant containers to store (or merely read) them directly in S...">ipc::shm::stl::Stateless_allocator</a>-backed STL-compliant structures (which, internally, includes <code>struc::Channel</code> messages) take care of any needed deallocation without the user worrying about it, so it does not break the aforementioned cross-process garbage collection. (First-class &ndash; outer &ndash; SHM-handles are clever cross-process <code>shared_ptr</code>s. Second-class &ndash; inner &ndash; SHM pointers are handled by bug-free STL-compliant code, such as boost.container containers and <code>flow::util::Basic_blob</code>.)</dd></dl>
<dl class="section user"><dt></dt><dd>It is only in the unlikely, and discouraged, case of storing explicit pointers in your C++ structures that the need to allocate/deallocate manually (without GC) might arise. As long as you avoid writing such code, this risk will not arise. However, one can do it more conscientiously by writing a custom allocator-compliant container. (In fact <code>flow::util::Basic_blob</code> is exactly that, to give an example.)</dd></dl>
<h3>Permissions; levels of permissions</h3>
<p ><a class="el" href="namespaceipc_1_1session.html" title="Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session conc...">ipc::session</a> and <a class="el" href="namespaceipc_1_1transport.html" title="Flow-IPC module providing transmission of structured messages and/or low-level blobs (and more) betwe...">ipc::transport</a> objects may require writing items into the file system; and those or other objects may need to read them there. Hence when writing a new item into a directory permissions are set; and various APIs accordingly take <a class="el" href="namespaceipc_1_1util.html#a1b398ae730d1e6040687cb2397115152" title="Short-hand for Unix (POSIX) permissions class.">ipc::util::Permissions</a> arguments. These <em>can</em> be specified directly in certain <a class="el" href="namespaceipc_1_1transport.html" title="Flow-IPC module providing transmission of structured messages and/or low-level blobs (and more) betwe...">ipc::transport</a> and <a class="el" href="namespaceipc_1_1shm.html" title="Modules for SHared Memory (SHM) support.">ipc::shm</a> APIs; for example some <a class="el" href="classipc_1_1transport_1_1Persistent__mq__handle.html" title="A documentation-only concept defining the behavior of an object representing a light-weight handle to...">ipc::transport::Persistent_mq_handle</a> and <a class="el" href="classipc_1_1shm_1_1classic_1_1Pool__arena.html" title="A SHM-classic interface around a single SHM pool with allocation-algorithm services by boost....">ipc::shm::classic::Pool_arena</a> constructors. (Directly would mean, for example, supplying an octal value such as 0644 to the <code>util::Permissions</code> constructor.)</p>
<p >However we recommend against doing so on 2 levels.</p><ul>
<li>Firstly if using <a class="el" href="namespaceipc_1_1session.html" title="Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session conc...">ipc::session</a> to open <a class="el" href="namespaceipc_1_1transport.html" title="Flow-IPC module providing transmission of structured messages and/or low-level blobs (and more) betwe...">ipc::transport</a> channels and/or create <a class="el" href="namespaceipc_1_1shm.html" title="Modules for SHared Memory (SHM) support.">ipc::shm</a> arenas, then one never needs to invoke such low-level <a class="el" href="namespaceipc_1_1transport.html" title="Flow-IPC module providing transmission of structured messages and/or low-level blobs (and more) betwe...">ipc::transport</a> and/or <a class="el" href="namespaceipc_1_1shm.html" title="Modules for SHared Memory (SHM) support.">ipc::shm</a> constructors anyway; the <code>Channel</code> and/or <code>Arena</code> of the appropriate type will be constructed internally, and permissions will be set without your direct involvement along with other painful details like resource names (<code>Shared_name</code>s).</li>
<li>Secondly, even if foregoing <a class="el" href="namespaceipc_1_1session.html" title="Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session conc...">ipc::session</a> and creating low-level objects directly, in practice most likely only certain specific permissions values are actually useful. Therefore we have provided <a class="el" href="namespaceipc_1_1util.html#a2ec0bfdddb41a1ef0403e4bb8967705d" title="Simple specifier of desired access permissions, usually but not necessarily translated into a Permiss...">ipc::util::Permissions_level</a> <code>enum</code> and <a class="el" href="namespaceipc_1_1util.html#abda2ce5bcdbc26ca63d667b87818439c" title="Maps general Permissions_level specifier to low-level Permissions value, when the underlying resource...">ipc::util::shared_resource_permissions()</a> that can be used as follows, e.g.: <code>const Permissions perms = shared_resource_permissions(Permissions_level::S_GROUP_ACCESS)</code>.</li>
</ul>
<p >All that aside, if using <a class="el" href="namespaceipc_1_1session.html" title="Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session conc...">ipc::session</a> as recommended, then you will need to worry about exactly one setting per session-server application, when <a href="./session_setup.html#universe_desc">configuring the IPC universe</a>: <a class="el" href="structipc_1_1session_1_1Server__app.html#abdcd9e8b0287f914496d45a99848be44" title="Specifies level of access for Client_apps (which must, also, be in m_allowed_client_apps at any rate)...">ipc::session::Server_app::m_permissions_level_for_client_apps</a>. In that Manual page we specified <a class="el" href="namespaceipc_1_1util.html#a2ec0bfdddb41a1ef0403e4bb8967705daa3e1d310128f18fe2f903bf3cba8849a" title="Allows access by resource-owning user (in POSIX/Unix identified by UID) and no one else.">ipc::util::Permissions_level::S_USER_ACCESS</a> and directed you to the present page for more discussion and more robust setups. So, welcome.</p>
<hr  />
<dl class="section user"><dt>Kernel-persistent runtime directory (/var/run)</dt><dd>Flow-IPC's <a class="el" href="namespaceipc_1_1session.html" title="Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session conc...">ipc::session</a> places some important non-temporary files into /var/run (in Linux); most notably PID files written by session-server applications and read by others. This is a sensible default in a production server environment. However it usually requires admin privilege on the session-server's part and thus may fail due to a permissions error (which is why we mention it in this Manual page). For test/debug purposes, and possibly other purposes, it may be useful to place these files in another location; for example the author uses $HOME/tmp/var/run (where $HOME is the user's home directory a/k/a ~).</dd></dl>
<dl class="section user"><dt></dt><dd>To do so, when <a href="./session_setup.html#universe_desc">defining the <code>Server_app</code></a>, set <a class="el" href="structipc_1_1session_1_1Server__app.html#a4fa3317f8c57042789940be94f872500" title="Absolute path to the directory (without trailing separator) in the file system where kernel-persisten...">ipc::session::Server_app::m_kernel_persistent_run_dir_override</a> to the absolute path. If not set the default (/var/run in Linux) shall be used. To be clear, shell things like literally "$HOME" or "~" may not be used inside this data member.</dd></dl>
<hr  />
<p >Let us now delve into the possible values for the aforementioned <code>Server_app::m_permissions_level_for_client_apps</code> setting and their implications for safety. <code>Permissions_level::S_NO_ACCESS</code> is essentially for test/debug scenarios only, so we won't talk about it.</p>
<h3>Permissions level: UNRESTRICTED</h3>
<p >This is the least safe setting for <code>m_permissions_level_for_client_apps</code>. <a class="el" href="namespaceipc_1_1util.html#a2ec0bfdddb41a1ef0403e4bb8967705da25bf1cdee66ff5f73914fd5b0ee996e9" title="Allows access by all. Implies, as well, at least as much access as S_GROUP_ACCESS and thus S_USER_ACC...">ipc::util::Permissions_level::S_UNRESTRICTED</a> will ensure that the relevant resources will never fail to be accessed by the relevant processes due to a permissions error. (Internally, producer-consumer items like PID files shall be 0644; while symmetrically accessed items like SHM pools and MQs shall be 0666.)</p>
<p >We would recommend against this in most production server setups. However, it is at least useful in initial development and possibly test/debug scenarios.</p>
<h3>Permissions level: USER_ACCESS</h3>
<p >This is, in our view, one of the two viable settings for <code>m_permissions_level_for_client_apps</code> in production; the other one being GROUP_ACCESS. <a class="el" href="namespaceipc_1_1util.html#a2ec0bfdddb41a1ef0403e4bb8967705daa3e1d310128f18fe2f903bf3cba8849a" title="Allows access by resource-owning user (in POSIX/Unix identified by UID) and no one else.">ipc::util::Permissions_level::S_USER_ACCESS</a> means access to a resource may fail if the accessing application is running as a different <b>user</b> than the writing application, even if they are in the same <b>group</b>. (Internally items shall have permissions mode 0600.)</p>
<p >Despite implying <em>more</em> restrictive permissions values, ironically to be usable in practice it will require a <em>less</em> fine-grained (safety-wise) user/group setup in your production server. That is, both applications in a split will need to be running as the <em>same user</em> (same UID and GID).</p>
<p >To summarize, you can set <code>m_permissions_level_for_client_apps = Permissions_level::S_USER_ACCESS</code> and then run the 2+ split-connected applications all as the same user (UID and GID).</p>
<p >This might be okay depending on your or your organization's philosophy on these matters. However, and particularly in IPC universes with 3 or more applications, you may opt for GROUP_ACCESS instead (which is what we would recommend for maximum fine-grainedness safety-wise):</p>
<h3>Permissions level: GROUP_ACCESS</h3>
<p ><a class="el" href="namespaceipc_1_1util.html#a2ec0bfdddb41a1ef0403e4bb8967705daa5508fa6037b9c0926cf7eb20af97a6d" title="Allows access by resource-owning user&#39;s containing group(s) (in POSIX/Unix identified by GID) and no ...">ipc::util::Permissions_level::S_GROUP_ACCESS</a> means access to a resource may fail if the accessing application is running as a different <b>group</b> than the writing application, but it will work if they're in the same group but are running as different users. (Internally, producer-consumer items like PID files shall be 0640; while symmetrically accessed items like SHM pools and MQs shall be 0660.)</p>
<p >With this setting, you may still run both applications as the same user (equal UID/GIDs); but you may now split up the owner user as follows:</p><ul>
<li>Same group (GID) for both applications.</li>
<li>Different user (UID) for the 2 applications.</li>
</ul>
<p >To summarize, you can set <code>m_permissions_level_for_client_apps = Permissions_level::S_GROUP_ACCESS</code> and then run the 2+ split-connected applications in the same group (same GID) but as distinct users (differing UIDs).</p>
<p >The next page is: <a class="el" href="universes.html">Multi-split Universes</a>.</p>
<hr  />
<center><b>MANUAL NAVIGATION:</b> <a class="el" href="session_app_org.html">Preceding Page</a> - <a class="el" href="universes.html">Next Page</a> - <a href="./pages.html"><b>Table of Contents</b></a> - <a class="el" href="namespaceipc.html"><b>Reference</b></a></center> </div></div><!-- contents -->
</div><!-- PageDoc -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu May 2 2024 23:56:35 for Flow-IPC by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
